#!/usr/bin/env perl
use warnings;
use strict;

#
# Aggregate .errors output from test_prediction by user or movie.
# Computes both mean error and mean squared error.
# Use: errors_by.pl movie | user
# Input: see test_prediction.cpp
# Output:
# user_or_movie_id num_probe_ratings mean_error \
#   mean_squared_error root_mse (root_mse*num_probe_ratings)
# sorted numerically by id in ascending order
#

my $argc = scalar(@ARGV);
$argc == 1 or die "see comments for usage";
my ($by) = @ARGV;
my $col;
if ($by eq "movie") {
  $col = 1;
} elsif ($by eq "user") {
  $col = 2;
} else {
  die "expected either 'movie' or 'user'; got $by.";
}

sub output {
  my ($last, $n, $total_error, $total_squared_error) = @_;
  my $mean_error = $total_error / $n;
  my $mean_squared_error = $total_squared_error / $n;
  my $rmse = sqrt($mean_squared_error);
  my $rmse_weighted = $rmse * $n;
  print "$last $n $mean_error $mean_squared_error $rmse $rmse_weighted\n";
}

open(ERRORS, "sort -g -k $col - |");
my $last = -1;
my $n = 0;
my $total_error = 0.0;
my $total_squared_error = 0.0;
while(<ERRORS>) {
  /(\d+)\s+(\d+)\s+(.*)/ or die "unexpected error line format $_";
  my $id = ($by eq "movie") ? $1 : $2;
  my $error = $3;

  # Print total by user when we get to next user block.
  if ($last == -1) { 
    $last = $id;
  } elsif ($id != $last) {
    output($last, $n, $total_error, $total_squared_error);
  
    $n = 0;
    $total_error = 0.0;
    $total_squared_error = 0.0;
    $last = $id;
  }

  $n += 1;
  $total_error += $error;
  $total_squared_error += $error*$error;
}
close(ERRORS);

output($last, $n, $total_error, $total_squared_error);
# Copyright (c) 2009 John Lees-Miller
# 
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
# 
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.

